package com.jdpc.weparty.service.pic

import com.jdpc.weparty.component.ServerConfig
import com.jdpc.weparty.entity.Banner
import com.jdpc.weparty.repository.PictureRepository
import com.jdpc.weparty.service.activity.ActivityService
import com.jdpc.weparty.service.activity.generateActivityInfo
import com.jdpc.weparty.service.user.UserService
import com.jdpc.weparty.service.user.generateUserInfo
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import org.springframework.web.multipart.MultipartFile
import java.awt.image.BufferedImage
import java.io.ByteArrayInputStream
import java.io.File
import java.lang.Exception
import javax.imageio.ImageIO
import javax.servlet.http.HttpServletResponse
import kotlin.random.Random

@Service
class PictureServiceImpl : PictureService {
    @Autowired
    private lateinit var serverConfig: ServerConfig

    @Autowired
    private lateinit var activityService: ActivityService

    @Autowired
    private lateinit var userService: UserService

    @Autowired
    private lateinit var pictureRepository: PictureRepository

    private val supportedFileType = listOf("PNG", "JPG", "JPEG")

    private fun readPic(parent: String, picName: String): BufferedImage {
        val file = File(parent, picName)
        if (!file.exists()) {
            throw Exception("图片不存在")
        }
        return ImageIO.read(file)
    }

    private fun responsePic(pic: BufferedImage, picName: String, response: HttpServletResponse) {
        var picType = picName.split(".")[1]
        if (picType == "jpg") {
            picType = "jpeg"
        }
        response.contentType = "image/$picType"
        val os = response.outputStream
        try {
            ImageIO.write(pic, picType, os)

        } catch (e: Exception) {
            e.printStackTrace()
        } finally {
            os.flush()
            os.close()
        }
    }

    override fun responseAvatar(response: HttpServletResponse, picName: String) {
        val pic = readPic(serverConfig.localPath + serverConfig.avatarPath, picName)
        responsePic(pic, picName, response)
    }

    override fun responseBanner(response: HttpServletResponse, picName: String, path: String) {
        val pic = readPic(serverConfig.localPath + serverConfig.bannerPath + path, picName)
        responsePic(pic, picName, response)
    }

    override fun saveAvatar(file: MultipartFile, userId: Int): String? {
        var type: String? = null
        file.originalFilename?.let {
            type = getFileType(it)
        } ?: return null
        if (!file.isEmpty) {
            type?.let {
                if (it.toUpperCase() in supportedFileType) { // 项目在容器中实际发布运行的根路径

                    val trueFileName = "user$userId.${it.toLowerCase()}"
                    // 设置存放图片文件的路径
                    val path = "${serverConfig.localPath}${serverConfig.avatarPath}/$trueFileName"
                    val f = File(path)
                    if (f.exists()) {
                        f.delete()
                    }
                    file.transferTo(File(path))
                    val url = "avatar/$trueFileName"
                    val user = userService.getUser(userId)
                    user?.let { u ->
                        u.avatar = url

                    } ?: return null
                    userService.changeInfo(userId, generateUserInfo(user))

                    return url
                }
            }
        }
        return null

    }

    override fun saveBanner(file: MultipartFile, aId: Int): String? {
        var type: String? = null
        var fileName = ""
        file.originalFilename?.let {
            type = getFileType(it)
            fileName = getFileName(it)
        } ?: return null
        if (!file.isEmpty) {
            type?.let {
                //判断图片文件类型
                if (it.toUpperCase() in supportedFileType) {
                    val activity = activityService.findActivity(aId) ?: return null

                    var finalFileName = "activities/$aId/$fileName.$type"
                    // 设置存放图片文件的路径
                    var path = "${serverConfig.localPath}${serverConfig.bannerPath}/$finalFileName"
                    var saveFile = File(path)
                    val random = Random(System.currentTimeMillis())
                    var randomPosition: Int
                    saveFile.parentFile?.let { parent ->
                        if (!parent.exists()) {
                            parent.mkdirs()
                        }
                    }
                    while (saveFile.exists()) {
                        randomPosition = random.nextInt() % 1000
                        finalFileName = "activities/$aId/$fileName$randomPosition.$type"
                        path = "${serverConfig.localPath}${serverConfig.bannerPath}/$finalFileName"
                        saveFile = File(path)
                    }
                    activity.activityPic = "banner/$finalFileName"

                    val buff = ImageIO.read(ByteArrayInputStream(file.bytes))
                    val picture = Banner().apply {
                        this.activity = activity
                        this.height = buff.height
                        this.width = buff.width
                        this.url = activity.activityPic
                    }
                    file.transferTo(saveFile)

                    pictureRepository.save(picture)
                    //修改数据库内的活动图片路径
                    activityService.changeActivityInfo(aId, generateActivityInfo(activity))

                    return activity.activityPic
                }
            }
        }
        return null

    }

    override fun saveBanner(files: List<MultipartFile>, aId: Int): List<String?> {
        val result = ArrayList<String?>()
        for (file in files) {
            result.add(saveBanner(file, aId))
        }
        return result
    }

    override fun deleteBanner(url: String): Pair<Boolean, String> {
        val finalFileName = url.substring(url.indexOf("banner/") + "banner/".length)
        val path = "${serverConfig.localPath}${serverConfig.bannerPath}/$finalFileName"
        val file = File(path)
        if (file.exists()) {
            val result = file.delete()
            return if (result) {
                Pair(result, "删除成功")
            } else {
                Pair(result, "删除失败")
            }
        }
        return Pair(false, "文件不存在")
    }

//    override fun getBanners(aId: Int): Set<Picture> {
//        return HashSet<Picture>(pictureRepository.findByActivityId(aId))
//    }

    private fun getFileName(originalFilename: String): String {
        val totalFileName = if (originalFilename.indexOf("/") != -1) {
            originalFilename.substring(originalFilename.lastIndexOf("/") + 1, originalFilename.length)
        } else {
            originalFilename
        }
        return totalFileName.substring(0, totalFileName.indexOf("."))
    }

    private fun getFileType(originalFilename: String): String? {
        return if (originalFilename.indexOf(".") != -1) originalFilename.substring(originalFilename.lastIndexOf(".") + 1, originalFilename.length) else null

    }
}